#include "Gamut.h"


Gamut::Gamut (bool isNormalized, bool isRGB) : PrimitiveObject (Vertex::P_ONLY), normalized (isNormalized), toRGB (isRGB)
{
}

void Gamut::fill (void)
{
   int xMaxPos = -1;
   int yMinPos = -1;
   float xMaxTmp = 0;
   float yMinTmp = 0;
   if (normalized == true) {
      yMinTmp = 1.0f;
      for (int i = 1; i < numCoords - 2; i++) {
         coordData[i] = glm::normalize (coordData[i]);
      }
      for (int i = 1; i < numCoords - 2; i++) {
         if (coordData[i].x >= xMaxTmp) {
            xMaxTmp = coordData[i].x;
            xMaxPos = i;
         }
         if (coordData[i].z >= 0.5) {
            if (coordData[i].y < yMinTmp) {
               yMinTmp = coordData[i].y;
               yMinPos = i;
            }
         }
      }
   }
   else {
      for (int i = 1; i < numCoords - 2; i++) {
         if (coordData[i].x >= xMaxTmp) {
            xMaxTmp = coordData[i].x;
            xMaxPos = i;
         }
         if (coordData[i].z >= yMinTmp) {
            yMinTmp = coordData[i].z;
            yMinPos = i;
         }
      }
   }
   indexData = new GLuint[numIndex];
   int k = 0;
   for (int i = 1; i < numCoords - 2; i++) {
      //black --> contour triangle
      indexData[k++] = i;
      indexData[k++] = i + 1;
      indexData[k++] = 0;
      //contour --> white triangle
      indexData[k++] = i;
      indexData[k++] = numCoords - 1;
      indexData[k++] = i + 1;
   }   
   //bottom triangle
   indexData[k++] = yMinPos;
   indexData[k++] = 0;
   indexData[k++] = xMaxPos;
   indexData[k++] = yMinPos;
   indexData[k++] = xMaxPos;
   indexData[k++] = numCoords - 1;
   printf ("\nx[%d] %.2f  z[%d] %.2f", xMaxPos, xMaxTmp, yMinPos, yMinTmp);
}

void Gamut::genBuffer (void)
{
   glGenVertexArrays (1, &VAOHandle);
   glBindVertexArray (VAOHandle);
   glGenBuffers (1, &vertexID);
   glBindBuffer (GL_ARRAY_BUFFER, vertexID);
   glBufferData (GL_ARRAY_BUFFER, numCoords*sizeof(glm::vec3), coordData, GL_STATIC_DRAW);

   glEnableVertexAttribArray (attribLoc[0]);
   glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), NULL);

   glGenBuffers (1, &indexID);
   glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, indexID);
   glBufferData (GL_ELEMENT_ARRAY_BUFFER, numIndex*sizeof(GLuint), indexData, GL_STATIC_DRAW);

   glBindVertexArray (0);//free Bind

   delete[] coordData;
   delete[] indexData;
}
void Gamut::freeBuffer (void)
{
   glDeleteBuffers (1, &vertexID);
   glDeleteBuffers (1, &indexID);
}
//public: 
void Gamut::init (void)
{
   fill ();
   genBuffer ();
}
void Gamut::draw (void)
{
   glBindVertexArray (VAOHandle);
   // glDrawElements (GL_TRIANGLES, numIndex, GL_UNSIGNED_INT, NULL);
   glDrawArrays (GL_POINTS, 0, numCoords);
   glBindVertexArray (0);
}
void Gamut::setCoordData (glm::vec3 *cd)
{
   coordData = new glm::vec3[numCoords];
   if (toRGB == true) {
      for (int i = 0; i < numCoords; i++) {
         corCIEXYZtosRGB (cd[i].x, cd[i].y, cd[i].z, &coordData[i].x, &coordData[i].y, &coordData[i].z, D65);         
      }
   }
   else {
      for (int i = 0; i < numCoords; i++) {   
         coordData[i] = cd[i];
      }
   }
}
void Gamut::setNumCoords (const int &n)
{
   numCoords = n;
   numIndex = 6 * (n - 3) + 6; // 6 = bottom triangles
}
Gamut::~Gamut ()
{
}
